package clientMain;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;

import lib.StreamSocket;

public class Parser {

	// Is this a valid coffee request?
	static private boolean validateProtocol(String request) {
		boolean valid = false;
		if (request.startsWith("coffee://")) {
			valid = true;
		}
		return valid;
	}

	// The Java URL class has a set of protocols it allows. As "coffee://" is
	// not in the set we will have to replace the string with "http:// to be
	// able to use the URL class.
	static private String replaceProtocol(String request) {
		request = request.replaceFirst("coffee://", "http://");
		return request;
	}

	// Return the host specified in the request
	static public String getHost(String request) {
		String host = "";
		if (validateProtocol(request)) {
			try {
				URL url = new URL(replaceProtocol(request));
				host = url.getHost();
			} catch (MalformedURLException e) {
				System.out.println("Bad stuff happened");
				// exception handler code here
				// ...
			}
		}
		return host;
	}

	// Return the pot specified in the request
	static private String getPotDesignator(String request) {
		String pot = " ";
		if (validateProtocol(request)) {
			try {
				URL url = new URL(replaceProtocol(request));
				if ((!((url.getPath()).equals("/")))) {
					if ((!((url.getPath()).equals("")))) {

						pot = " " + url.getPath() + " ";
					}
				}
			} catch (MalformedURLException e) {
				System.out.println("Bad stuff happened");
				// exception handler code here
				// ...
			}
		}
		return pot;
	}

	// Return the additions specified in the request
	static private String getAdditions(String request) {
		String additions = "";
		if (validateProtocol(request)) {
			try {
				URL url = new URL(replaceProtocol(request));
				if (url.getQuery() != null) {
					additions = url.getQuery();
				}
			} catch (MalformedURLException e) {
				System.out.println("Bad stuff happened");
				// exception handler code here
				// ...
			}
		}
		return additions;
	}

	// Format the additions for the head
	static private String processAdditions(String additionslist) {
		String additions = "";
		String additionsListArray[];
		if (additionslist.equals("*")) {
			additions = "\naccept-additions:*";
		} else if (!(additionslist.equals(""))) {
			additionslist = additionslist.replaceAll("=", ";");
			additionsListArray = additionslist.split("&");
			additions = "\naccept-additions:";
			for (String thisAddition : additionsListArray) {
				String thisAdditions = (thisAddition.split(";")[1]);

				additions += thisAdditions + ";";
			}
		}
		additions += "\r\n\r\n";
		return additions;
	}

	// Create the BREW message to be send to server
	static private String createBrewMessage(String request) {
		String head = "";
		if (validateProtocol(request)) {
			head = "BREW" + getPotDesignator(request) + "HTCPCP/1.0 \r"
					+ processAdditions(getAdditions(request));
		}
		return head;
	}

	static private String createGetMessage(String request) {
		String head = "";
		if (validateProtocol(request)) {
			head = "GET" + getPotDesignator(request) + "HTCPCP/1.0 \r\n\r\n";
		}
		return head;
	}

	static private String createWhenMessage(String request) {
		String head = "";
		if (validateProtocol(request)) {
			head = "WHEN" + getPotDesignator(request) + "HTCPCP/1.0 \r\n\r\n";
		}
		return head;
	}

	static private String createPropfindMessage(String request) {
		String head = "";
		if (validateProtocol(request)) {
			head = "PROPFIND" + getPotDesignator(request)
					+ "HTCPCP/1.0 \r\n\r\n";
		}
		return head;
	}

	static public String parseRequest(String request, StreamSocket streamServer) {
		if (!(getHost(request).equals(""))
				|| (getHost(request).equals(streamServer.getCurrentHost()))) {
			try {
				streamServer.updateHost(getHost(request));
			} catch (UnknownHostException e) {
				System.out.print("Host not found\n");
				try {
					streamServer.kill();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				return "";
			} catch (IOException e) {
				e.printStackTrace();
			} 
		}

		if (getAdditions(request).equals("")) {
			return createGetMessage(request);
		} else if (getAdditions(request).equalsIgnoreCase("when")) {
			return createWhenMessage(request);
		} else if (getAdditions(request).equalsIgnoreCase("propfind")) {
			return createPropfindMessage(request);
		} else {
			return createBrewMessage(request);
		}

	}

	static public String parseResponse(String response) {
		return response.replaceAll("\r\n", "").replaceAll("HTCPCP/1.0 ", "")
				.replaceAll("accept-additions:", "").replaceAll(";", ", ");
	}
}
